/*
	题目描述：

	一个括号序列是指一个由'(', ')', '[', ']'四种字符组成的字符串。

	一个只包含数字，加号'+'，和上述四种括号的合法算数表达式，去掉数字和加号之后得到的括号序列成为合法的括号序列。我们定义空串也是合法的括号序列。

	例如(1) + [2], ([3]), 4 + [5]相应的括号序列 "()[]", "([])", "[]"都是合法的括号序列。而(6 + 7], [8 + ((9对应的"(]", "[(("则是非法的。

	字符串s0s1s2⋯s|s|−1的子串s[l,r](0≤ l≤r<|s|)是指slsl+1⋯sr。

	现在给定一个括号序列，请找出其中的一个子串，使得这个子串是合法的括号序列，且包含的'['数量最多。


	输入：

	一个括号序列s。1≤|s|≤5×105

	输出：

	第一行，答案要求的子串中包含'['的数量。

	如果答案是0，输出到此为止，否则：

	第二行，两个整数l, r。表示子串第一个字符的位置和最后一个字符的位置。

	如果有多个满足条件的字符串，请输出使得子串长度最大的答案。如果长度最大的仍有多个，请输出r最大的。
 */


#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#if defined(_WIN32) && !defined(__cplusplus)
#define inline __inline
#endif

#define max(a,b)    (((a) > (b)) ? (a) : (b))

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef _DEBUG
#include <assert.h>
#endif

#define Api static inline

typedef struct {
	char Ch;
	int Index;
}InputItem;

typedef struct {
	// int StartIndex;
	int EndIndex;
}OutputPair;

typedef struct {
	int StartIndex;
	int EndIndex;
	int SquareBracketNum;
}OutputItem;


typedef InputItem SElemType;
#define TRUE 1
#define FALSE 0
typedef int BOOL;	/* Boolean是布尔类型,其值是TRUE或FALSE */


#define MAX_STACK_SIZE 500005  
#define STACK_SIZE_INCREMENT 10000  
typedef struct
{
	int stacksize;
	int top, base;
	SElemType *data;
}SqStack;


Api void StackInit(SqStack *stack, int size)
{
	stack->top = stack->base = 0;
	stack->data = (SElemType *)malloc(sizeof(SElemType) * size);
	stack->stacksize = size;
}

Api BOOL StackEmpty(const SqStack *stack)
{
	return stack->top == stack->base;
}

Api void StackPush(SqStack *stack, const SElemType *e)
{
	//#ifdef _DEBUG
	//	assert(stack->top - stack->base < stack->stacksize);
	//#endif
	//if (stack->top - stack->base >= stack->stacksize)
	//{
	//	stack->stacksize += STACK_SIZE_INCREMENT;
	//	stack->data = (SElemType *)realloc(stack->data, sizeof(SElemType) * (stack->stacksize));
	//}
	stack->data[stack->top] = *e;
	++stack->top;
}

Api void StackPop(SqStack *stack)
{
#ifdef _DEBUG
	assert(!StackEmpty(stack));
#endif
	--stack->top;
	// return stack->data[stack->top];
}

Api void StackClear(SqStack *stack)
{
	stack->top = 0;
	stack->base = 0;
	// stack->stacksize = MAX_STACK_SIZE;
}

Api SElemType GetStackTop(const SqStack *stack)
{
#ifdef _DEBUG
	assert(!StackEmpty(stack));
#endif
	return stack->data[stack->top - 1];
}

Api BOOL IsBracketMatch(char left, char right)
{
	if (left == '(' && right == ')') return TRUE;
	if (left == '[' && right == ']') return TRUE;
	// if (left == '{' && right == '}') return TRUE;
	return FALSE;
}

Api void UpdateOutputItem(const OutputItem *temp, OutputItem *final)
{
	int tempLen = temp->EndIndex - temp->StartIndex;
	int tempNum = temp->SquareBracketNum;
	int finalLen = final->EndIndex - final->StartIndex;
	int finalNum = final->SquareBracketNum;
	if (tempNum > finalNum
		|| (tempNum == finalNum && tempLen > finalLen)
		|| (tempNum == finalNum && tempLen == finalLen	&& temp->EndIndex > final->EndIndex))
	{
		memcpy(final, temp, sizeof(OutputItem));
	}
}

static OutputPair OutputPairs[MAX_STACK_SIZE];
static char Input[MAX_STACK_SIZE];

int main()
{
	SqStack stack;
	StackInit(&stack, MAX_STACK_SIZE);
	int index = -1;

	while (1)
	{
		char ch = getchar();
		if (ch == '\n') break;
		++index;
		Input[index] = ch;
		switch (ch)
		{
			case ')':
			case ']':
			{
				if (!StackEmpty(&stack))
				{
					SElemType top = GetStackTop(&stack);
					if (IsBracketMatch(top.Ch, ch))
					{
						StackPop(&stack);
						// OutputPairs[top.Index].StartIndex = top.Index;
						OutputPairs[top.Index].EndIndex = index;
					}
					else StackClear(&stack);
				}
				break;
			}
			default:
			{
				InputItem item = { ch, index };
				StackPush(&stack, &item);
				break;
			}
		}
	}
	Input[index + 1] = 0;

	OutputItem final = { 0, 0, 0 };
	OutputItem temp = { 0, 0, 0 };
	for (int i = 0; i < index;)
	{
		if (i + final.SquareBracketNum > index) break;

		temp.StartIndex = i;
		temp.EndIndex = 0;
		temp.SquareBracketNum = 0;
		while (OutputPairs[i].EndIndex != 0)
		{
			temp.EndIndex = OutputPairs[i].EndIndex;
			i = temp.EndIndex + 1;
		}
		if (temp.EndIndex > temp.StartIndex)
		{
			for (int j = temp.StartIndex; j < temp.EndIndex; ++j)
			{
				if (Input[j] == '[') ++temp.SquareBracketNum;
			}
			UpdateOutputItem(&temp, &final);
		}
		else ++i;
	}

	if (final.SquareBracketNum > 0)
	{
		printf("%d\n", final.SquareBracketNum);
		printf("%d %d\n", final.StartIndex, final.EndIndex);
	}
	else printf("0\n");

	// StackClear(&stack);
	// getchar();
	return 0;
}
